<?php
require_once './lib/simple_html_dom.php';

define("DEFAULT_ENCODING", "UTF-8");

///////////////////////////////
function startsWith ($haystack, $needle, $case = false){
	if ($case)
		return strpos($haystack, $needle, 0) === 0;
	return stripos($haystack, $needle, 0) === 0;
}

function endsWith($haystack, $needle){
	$length = strlen($needle);
	if ($length == 0) {
		return true;
	}
	return (substr($haystack, -$length) === $needle);
}
////////////////////////////////

function getEncoding($text) {
	$encoding = 'auto';
	if (mb_check_encoding($text, 'gbk')) {
		$encoding = 'gbk//IGNORE';
	} else if (mb_check_encoding($text, 'utf-8')){
		$encoding = 'utf-8';
	}
	
	//error_log('encoding:'.$encoding);
	return $encoding;
}

/**
 * Detect the charset encoding of text
 * @param $text html text for checking encoding
 * @param null|array $info the info about returned data
 * @return string charset encoding name
 */
function detectEncoding($text, $info = null) {
	$encoding = DEFAULT_ENCODING;
	if ($info && isset($info['content_type'])) {
		$content_type = $info['content_type'];
		$exploded = explode(';', $content_type);
		foreach ($exploded as $val) {
			if (startsWith($val, 'charset=')) {
				$encoding = substr($val, strlen('charset='));
			}
		}
	}
	if ($encoding == DEFAULT_ENCODING && $text) {
		preg_match_all("/<meta.+?charset=([-\w]+)/i", $text, $matches);
		//error_log('-->'.var_export($matches, true));
		if ($matches[1] && count($matches[1])) {
			$encoding = $matches[1][0];
		}
	}

	return $encoding;
}

function fixStyleImages($content, $url) {
	//$styleImageRegex = "#background[^<>]*\burl\b\(.*\)$#i";
	$pattern = '/(?<=[background-image|background])\s*:\s*url\s*\(\s*[\'"]{0,1}\s*([^\'"]*?)\s*[\'"]{0,1}\s*\)/i';
	$matches = array();
	preg_match_all($pattern, $content, $matches);
	//error_log(var_export(array_unique($matches[1]), true));
	if ($matches[1]) {
		$parsedUrl = parse_url($url);
		$newUrl = $parsedUrl['scheme'].'://'.$parsedUrl['host'];
		$imageMatches = array_unique($matches[1]);
		$folder = dirname(dirname(__FILE__)).'\\urls\\';
		$folder .= $parsedUrl['host'];
		foreach ($imageMatches as $match) {
			if (startsWith($match, '/') && !startsWith($match, '//')) {
				//$img = file_get_contents($newUrl.$match);
				//error_log("save file to: ".$folder.$match);
				//file_put_contents($folder.$match, $img);
			}
		}
	}
}

function getUrl($url) {
	$result = curl_get_url($url);
	//error_log(var_export($result['info'], true));
	$redirect = false;
	$url2 = $result['info']['url'];
	if (strcasecmp($url, $url2) != 0) {
		$redirect = true;
		// set it to session
		$_SESSION['REDIRECT_URL'] = $url2;
	}

	$parsedUrl = parse_url($result['info']['url']);
	//$content = file_get_html($url);

	fixStyleImages($result['content'], $url);

	$content = str_get_html($result['content']);
	
	$newUrl = $parsedUrl['scheme'].'://'.$parsedUrl['host'].((isset($parsedUrl['port']) && $parsedUrl['port'] != 80) ? ':'.$parsedUrl['port'] : "");
	error_log('[getUrl] new url: '.$newUrl);
	if ($content && $redirect) {
		$_url = $result['info']['url'];

		foreach ($content->find('link') as $element) {
			if ($element->rel != 'stylesheet') {
				continue;
			}
			if ($element->href) {
				if (startsWith($element->href, '/')) {
					$element->href = $newUrl.$element->href;
				} else if (startsWith($element->href, '../')) {
					$pieces = explode('../', $element->href);
					$count = count($pieces);
					$fixed_url = $_url;
					for($i = 0; $i < $count; $i++) {
						$ipos = strripos($fixed_url, '/');
						$fixed_url = mb_substr($fixed_url, 0, $ipos);
					}
					error_log("Fixed url: ".$fixed_url.'/'.$pieces[$count - 1]);
					$element->href = $fixed_url.'/'.$pieces[$count - 1];
				} elseif (startsWith($element->href, 'http://') || startsWith($element->href, 'https://')) {
					// not change
				} else {
					$ipos = strripos($_url, '/');
					$element->href = mb_substr($_url, 0, $ipos).'/'.$element->href;
				}
			}
		}

		// script fix
		foreach ($content->find('script') as $element) {
			if ($element->src) {
				//error_log('[getUrl] before script: '.$element->src);
				if (startsWith($element->src, '/')){
					$element->src = $newUrl.$element->src;
				} else if (startsWith($element->src, './')) {
					$element->src = $url2.$element->src;
				} else if (startsWith($element->src, '../')) {
					// TODO: check the count of '../' and set the url for tag
					error_log('++++++++++++++++++++++++++++++++');
					$pieces = explode('../', $element->src);
					$count = count($pieces);
					$fixed_url = $_url;
					for($i = 0; $i < $count; $i++) {
						$ipos = strripos($fixed_url, '/');
						$fixed_url = mb_substr($fixed_url, 0, $ipos);
					}
					$element->src = $fixed_url.'/'.$pieces[$count - 1];
				} elseif (startsWith($element->src, 'http://') || startsWith($element->src, 'https://')) {
					// not changed
				} else {
					$element->src = $url2.$element->src;
				}
				error_log('[getUrl] after script: '.$element->src);
			}
		}

		// image fix
		foreach ($content->find('img') as $element) {
			if ($element->src) {
				error_log('image url:'.$element->src);
				if (startsWith($element->src, '/')) {
					$element->src = $newUrl.$element->src;
				} else if (!startsWith($element->src, 'https') && !startsWith($element->src, 'http')) {
					if ($_url != $url) {
						$ipos = strripos($_url, '/');
						//error_log(mb_substr($_url, 0, $ipos));
						$element->src = mb_substr($_url, 0, $ipos).'/'.$element->src;
					}
				} else {
					$element->src = $newUrl.$element->src;
				}
			}
		}
	} else if($result['errno'] != 0) {
		error_log("[getUrl] CURL INFO: ".var_export($result['info'], true));
		error_log("[getUrl] CURL INFO: ".var_export($result['errno'], true));
		error_log("[getUrl] CURL INFO: ".var_export($result['error'], true));

        $content = $result['error'];
	}
	
	return array('content'=>$content);
}

// use curl to fetch the files of the url
// we can also use wget, for example: wget -E -H -k -K -p -e robots=off -P baidu www.baidu.com
function curl_get_url($url, $acceptCharset='utf-8,ISO-8859-1', $acceptLanguage='zh-CN,en-us,en') {
	
	$result = array();
	$parsedUrl = parse_url($url);
	
	$ch = curl_init();
	
	// Setup headers
	$header[0] = "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
	$header[] = "Cache-Control: max-age=0";
	$header[] = "Connection: keep-alive";
	$header[] = "Keep-Alive: 300";
	$header[] = "Accept-Charset: $acceptCharset;q=0.7,*;q=0.7";
	$header[] = "Accept-Language: $acceptLanguage;q=0.5";
	$header[] = "Pragma: "; // browsers keep this blank
	
	$cookie_file = 'cookies/'.$parsedUrl['host'].".txt";
	curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); // set cookie
	curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
	
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_REFERER, $url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
	curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
	curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt($ch, CURLOPT_TIMEOUT, 30);
	
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
	curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
	
	// method 1, not varify the ssl certificate
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
	curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
	
	// method 2, save the ssl certificate
	// curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true); ;
	// curl_setopt($ch,CURLOPT_CAINFO,dirname(__FILE__).'/cacert.pem');
	
	$content = curl_exec($ch);
	$curl_errno = curl_errno($ch);
	$curl_error = curl_error($ch);
	$curl_info = curl_getinfo($ch);
	curl_close($ch);
	
	$result['info'] = $curl_info;
	$result['content'] = '';
	$result['errno'] = $curl_errno;
	$result['error'] = $curl_error;
	if ($curl_errno == 0){
		$encoding = detectEncoding($content, $result['info']);
        header('content-type: text/html; charset=utf-8');
		$content = iconv($encoding, 'UTF-8//IGNORE', $content);//mb_convert_encoding($content, 'utf-8', 'GBK,UTF-8,ASCII');
		$result['content'] = $content;
	}
	
	return $result;
}

/**
 * Get value from $_POST or $_GET
 * @param string $name
 * @param mixed $defaultValue
 * @return mixed
 */
function getVar($name, $defaultValue = null) {
	if (isset($_POST[$name])) {
		return $_POST[$name];
	}
	
	if (isset($_GET[$name])) {
		return $_GET[$name];
	}
	
	return $defaultValue;
}

/**
 * Save the include file to a parameter
 * @param string $filename
 * @param array $vars
 * @return bool|string
 */
function get_include_contents($filename, $vars=array()) {
	if (is_file($filename)) {
		ob_start();
		$VARS = $vars;
		include $filename;
		$contents = ob_get_contents();
		ob_end_clean();
		return $contents;
	}
	return false;
}